package com.jfirer.mvc.core;

import com.jfirer.baseutil.StringUtil;
import com.jfirer.baseutil.reflect.ReflectUtil;
import com.jfirer.mvc.core.action.Action;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

/**
 * 充当路径分发器的类，用来根据地址规则转发数据请求
 *
 * @author 林斌（eric@jfire.cn）
 */
@WebServlet(name = "EasyMvcDispathServlet", value = "/*", loadOnStartup = 1, asyncSupported = true)
@MultipartConfig
public class EasyMvcDispathServlet extends HttpServlet
{
    private static final long                 serialVersionUID  = 6091581255799463902L;
    private static final Logger               logger            = LoggerFactory.getLogger(EasyMvcDispathServlet.class);
    public static final  String               CONFIG_CLASS_NAME = "jfire.mvc.configClassName";
    private              DispathServletHelper helper;
    public static        int                  SERVLET_VERSION;

    @Override
    public void init(final ServletConfig servletConfig) throws ServletException
    {
        SERVLET_VERSION = detectVersion(servletConfig);
        logger.debug("初始化mvc框架,当前servlet版本:{}", SERVLET_VERSION);
        helper = new DispathServletHelper(StringUtil.isNotBlank(servletConfig.getInitParameter(CONFIG_CLASS_NAME)) ? servletConfig.getInitParameter(CONFIG_CLASS_NAME) : findConfigClassNameFromFile(), servletConfig.getServletContext());
    }

    String findConfigClassNameFromFile()
    {
        InputStream inputStream = EasyMvcDispathServlet.class.getClassLoader().getResourceAsStream("mvc.config");
        if (inputStream != null)
        {
            try
            {
                byte[] src = new byte[inputStream.available()];
                inputStream.read(src);
                return new String(src, Charset.forName("utf8"));
            }
            catch (Exception e)
            {
                ReflectUtil.throwException(e);
                return null;
            }
        }
        else
        {
            return null;
        }
    }

    int detectVersion(ServletConfig servletConfig)
    {
        int            version;
        ServletContext context      = servletConfig.getServletContext();
        int            majorVersion = context.getEffectiveMajorVersion();
        int            minorVersion = context.getEffectiveMinorVersion();
        version = majorVersion * 10 + minorVersion;
        return version;
    }

    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
    {
        HttpServletRequest  request  = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        helper.preHandle(request, response);
        Action action = helper.getAction(request);
        if (action == null)
        {
            helper.handleStaticResourceRequest(request, response);
            return;
        }
        try
        {
            action.render(request, response);
        }
        catch (Throwable e)
        {
            logger.error("访问action出现异常,action为{}", action.getRequestUrl(), e);
            response.sendError(500, e.getLocalizedMessage());
        }
    }
}
